﻿// Call2.cpp : 定义 DLL 的初始化例程。
//

#include "stdafx.h"
#include "Call2.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#pragma data_seg("shared")
_ShareMemory sharedData[] =
{
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
    {0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

};
#pragma data_seg()
#pragma comment(linker, "/SECTION:shared,RWS")


BEGIN_MESSAGE_MAP ( CCall2App, CWinApp )
END_MESSAGE_MAP()
CCall2App::CCall2App() {}
CCall2App theApp;
tlbb* tl = NULL;

BOOL CCall2App::InitInstance()
{
    return CWinApp::InitInstance();
}

int CCall2App::ExitInstance()
{
    AFX_MANAGE_STATE ( AfxGetStaticModuleState() );
    if ( tl != NULL )
    {
        delete tl;
    }
    return CWinApp::ExitInstance();
}

LRESULT CALLBACK KEYBOARD_PRO ( int CODE, WPARAM wParam, LPARAM lParam )
{
    AFX_MANAGE_STATE ( AfxGetStaticModuleState() );
    if ( tl == NULL )
    {
        //创建窗口
        tl = new tlbb();
        tl->Create ( IDD_DIALOG1 );
        tl->ShowWindow ( /*SW_SHOW*/ SW_HIDE );
        //累计加载避免被卸载了
        TCHAR pathChar[MAX_PATH];
        GetModuleFileName ( theApp.m_hInstance, pathChar, MAX_PATH );
        HMODULE hMode = ::LoadLibrary ( pathChar );
        int index =  RecPidHwnd ( _getpid(), tl->GetSafeHwnd() );

        tl->myShareMemory = sharedData+index;
        tl->aa = sharedData[index].Data;
        //AfxMessageBox ( L"AAA" );
    }
    return  CallNextHookEx ( NULL, CODE, wParam, lParam );
}

bool _stdcall SetHook ( DWORD PID, HWND* hWnd, int* shareID )
{
    AFX_MANAGE_STATE ( AfxGetStaticModuleState() );
    DWORD tid;
    DWORD pid;
    HWND hwnd = NULL;
    hwnd = GetTopWindow ( NULL );
    char windowClassName[MAX_PATH];
    while ( hwnd )
    {
        tid = GetWindowThreadProcessId ( hwnd, &pid );
        if ( IsWindow ( hwnd ) && pid == PID )
        {
            RealGetWindowClassA ( hwnd, windowClassName, MAX_PATH );
            if ( strcmp ( windowClassName, "TianLongBaBu WndClass" ) == 0 )
            {
                HHOOK hr = SetWindowsHookExW ( WH_CALLWNDPROC, KEYBOARD_PRO, theApp.m_hInstance, tid );
                Sleep ( 200 );
                SendMessage ( hwnd, WM_NULL, NULL, NULL ); //发送消息让HOOK执行
                *hWnd = hwnd;
                UnhookWindowsHookEx ( hr );
                *shareID = GetHwndFromPID ( pid );
                return true;
            }
            memset ( windowClassName, 0, MAX_PATH );
        }
        hwnd = GetNextWindow ( hwnd, GW_HWNDNEXT );
    }
    return false;
}

bool  _stdcall UseCall ( DWORD ShareID, DWORD funcID, DWORD* args, DWORD ArrLen )
{
    AFX_MANAGE_STATE ( AfxGetStaticModuleState() );
    //内存复制
    memcpy ( sharedData[ShareID].Data, args, sizeof ( int ) *ArrLen );
    ::SendMessageA ( sharedData[ShareID].hWnd , MY_CALL , funcID, NULL );
    return true;
}

//返回的是占用的共享段
int _stdcall GetHwndFromPID ( DWORD pid )
{
    for ( int i = 0; i < 25; i++ )
    {
        if ( sharedData[i].PID == pid )
        {
            return i;
        }
    }
    return 0;
}

int RecPidHwnd ( int pid, HWND hwnd )
{
    for ( int i = 0; i < 25; i++ )
    {
        if ( sharedData[i].PID == 0 )
        {
            sharedData[i].PID = pid;
            sharedData[i].hWnd = hwnd;
            return  i;
        }
    }
    return -1;
}